﻿using UnityEngine;
using System.Collections;

public class EnergyShotManager : MonoBehaviour, IResettable {

    public float minimumVelocity = 1.0f;
    public float markerDistance = 0.4f;
    public GameObject shotMarker;
    public bool curveWithAccelerometer = true;
    public GameObject owner;
    public int maxBounces = 10;

    private int bounces = 0;
    private bool hasHadVelocity = false;
    private AccelerometerReader accelerometerReader = null;
    private Vector3 lastAccelerometerReader = Vector3.zero;
    private float bounceMultiplier = 1.0f;
    private Vector3 lastMarkerPosition;
    private float timeAlive = 0.0f;

	private AudioSource bounceAudio;

	// Use this for initialization
	void Start () {

        accelerometerReader = GameObject.FindGameObjectWithTag("accelerometer").GetComponent<AccelerometerReader>();
        lastAccelerometerReader = accelerometerReader.lowPassValue;
        ResetItemList.Instance.AddItem(this);
        lastMarkerPosition = this.transform.position;
        FollowActionPriorityQueue.Instance.AddFollowPosition(new EnergyShotPrioritizedFollowPosition(this));

		bounceAudio = transform.FindChild ("BounceNoise").GetComponent<AudioSource> ();

	}
	
	// Update is called once per frame
	void Update () {

        timeAlive += Time.deltaTime;

        if (this.rigidbody.velocity.magnitude > 0)
        {
            hasHadVelocity = true;
        }

        if (hasHadVelocity)
        {
            if (curveWithAccelerometer)
            {
                // We need to apply a lateral force with the change.
                float orientationChange = Vector3.Angle(lastAccelerometerReader, accelerometerReader.lowPassValue);
                Vector3 forceDirection = Quaternion.AngleAxis(-orientationChange, Camera.main.transform.forward) * this.rigidbody.velocity;
                
            }

            if (this.rigidbody.velocity.magnitude < minimumVelocity || bounces >= maxBounces) Remove();

            if (trailMarkers && (Vector3.Distance(lastMarkerPosition, this.transform.position) > markerDistance))
            {
                owner.GetComponent<RobotTouch>().shotMarkers.Add(GameObject.Instantiate(shotMarker, this.transform.position, Quaternion.identity) as GameObject);
                lastMarkerPosition = this.transform.position;
            }
        }

	}

    void LateUpdate()
    {
        if (bounceMultiplier != 1.0f)
        {
            this.rigidbody.velocity *= bounceMultiplier;
            bounceMultiplier = 1.0f;
        }
    }

    bool destroyed = false;
    public bool IsDestroyed { get { return destroyed; } }

    public void Reset()
    {
        if (!destroyed && this.gameObject != null)
        {
            destroyed = true;
            Destroy(this.gameObject);

            foreach (GameObject shotMarker in owner.GetComponent<RobotTouch>().shotMarkers)
            {
                Destroy(shotMarker);
            }
        }
    }


    public bool PersistAfterReset()
    {
        return false;
    }

    void OnDestroy()
    {
        destroyed = true;
    }

    bool trailMarkers = false;

    void OnCollisionEnter(Collision collision)
    {
		if (bounceAudio.isPlaying)
						bounceAudio.Stop ();
		bounceAudio.Play ();


        trailMarkers = false;

        if (collision.gameObject.tag == "bouncyWall")
        {
            bounceMultiplier = collision.gameObject.GetComponent<ForceBounciness>().velocityMultiplier;
        }

        bounces++;
    }

    internal void DisconnectTrail()
    {
        if (!destroyed)
        {
            Transform trail = transform.FindChild("TrailParticles");
            trail.parent = null;
            trail.GetComponent<FadeAfterShotDestroyed>().StartFade(timeAlive);
        }
    }

    internal void Remove()
    {
        DisconnectTrail();
        ResetItemList.Instance.RemoveItem(this);
        Destroy(gameObject);
        this.destroyed = true;
    }
}
